﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SimpleRest.Core
{
    /// <summary>
    /// Attribute used to indicate that a class is a REST service within this particular pipeline model.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class ServiceAttribute : Attribute
    {
        /// <summary>
        /// The major verstion associated to this attribute.
        /// </summary>
        public readonly int? MajorVersion;
        /// <summary>
        /// The minor version associated to this attribute.
        /// </summary>
        public readonly int? MinorVersion;
        /// <summary>
        /// The service root route URI associated to this service attribute.
        /// </summary>
        public readonly string ServiceRoot;
        /// <summary>
        /// A flag that determines if the version should be ignored, even though it was specified.  When this is true it
        /// means that GetVersionServiceRoot is not prefixed with the version.
        /// </summary>
        public readonly bool IgnoreVersionPrefix;

        public ServiceAttribute(string serviceRoot)
        {
            this.ServiceRoot = serviceRoot;
        }
        public ServiceAttribute(string serviceRoot, int majorVersion)
            : this(serviceRoot)
        {
            this.MajorVersion = majorVersion;
        }
        public ServiceAttribute(string serviceRoot, int majorVersion, bool ignoreVersionPrefix)
            : this(serviceRoot, majorVersion)
        {
            this.IgnoreVersionPrefix = ignoreVersionPrefix;
        }
        public ServiceAttribute(string serviceRoot, int majorVersion, int minorVersion)
            : this(serviceRoot, majorVersion)
        {
            this.MinorVersion = minorVersion;
        }
        public ServiceAttribute(string serviceRoot, int majorVersion, int minorVersion, bool ignoreVersionPrefix)
            : this(serviceRoot, majorVersion, minorVersion)
        {
            this.IgnoreVersionPrefix = ignoreVersionPrefix;
        }

        private Version _version;
        /// <summary>
        /// The version object associated to this service.
        /// </summary>
        public Version Version
        {
            get
            {
                if (_version != null)
                    return _version;
                else
                {
                    if (this.MajorVersion.HasValue && this.MinorVersion.HasValue)
                        _version = new Version(this.MajorVersion.Value, this.MinorVersion.Value);
                    else if (!this.MajorVersion.HasValue && this.MinorVersion.HasValue)
                        _version = new Version(0, this.MinorVersion.Value);
                    else if (this.MajorVersion.HasValue && !this.MinorVersion.HasValue)
                        _version = new Version(this.MajorVersion.Value, 0);
                    else
                        _version = new Version(0, 0);

                    return _version;
                }
            }
        }

        /// <summary>
        /// Returns a string major.minor version representation of this service.
        /// </summary>
        /// <returns></returns>
        public string GetVersion()
        {
            string version = "";
            if (this.MajorVersion.HasValue)
                version = this.MajorVersion.ToString();
            if (this.MinorVersion.HasValue)
                version += "." + this.MinorVersion.ToString();

            return version;
        }

        /// <summary>
        /// Returns the true service route (including the version) for this service.
        /// </summary>
        /// <returns></returns>
        public string GetVersionServiceRoot()
        {
            string version = this.GetVersion();
            if (string.IsNullOrEmpty(version))
                return this.ServiceRoot == null ? "" : this.ServiceRoot;
            else
            {
                if (!this.IgnoreVersionPrefix)
                    return "v" + version + "/" + (this.ServiceRoot == null ? "" : this.ServiceRoot);
                else
                    return this.ServiceRoot;
            }
        }
    }
}
